/*
 * Copyright (C) 2021 XRADIO TECHNOLOGY CO., LTD. All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *    1. Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *    2. Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the
 *       distribution.
 *    3. Neither the name of XRADIO TECHNOLOGY CO., LTD. nor the names of
 *       its contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ohos_init.h"
#include "kernel/os/os.h"
#include "iot_gpio.h"
#include "wifi_device.h"
#include "cJSON.h"
#include "lwip/sockets.h"
#include "tcp_net_socket.h"

static void wifi_connect(char *ssid, char *passwd);

static OS_Thread_t g_main_thread;

static void MainThread(void *arg)
{
	unsigned int led_pin = 21; /* GPIOA_PIN21 */
	unsigned int key_pin = 11; /* GPIOA_PIN11 */
	IotGpioValue key_value;
	int led_value = 0;
	unsigned int tem = 0, hum = 0, s = 0;
	cJSON* dev_dat = NULL;
    int sfd = 0;
    int cfd = 0;
	char send_buf[512] = {0};
	char recv_buf[512] = {0};

	wifi_connect("GL-MT300N-V2-0be", "goodlife");

	IoTGpioInit(led_pin);
	IoTGpioSetDir(led_pin, IOT_GPIO_DIR_OUT);
	IoTGpioInit(key_pin);
	IoTGpioSetDir(key_pin, IOT_GPIO_DIR_IN);

	sfd = tcp_server_init(8080);
    cfd = tcp_server_accept(sfd);

	while (1) {
		srand( s++ );
		tem = rand()%10 + 20;
		hum = rand()%20 + 40;
		IoTGpioGetInputVal(key_pin, &key_value);
		printf("kw : hello world! key : %d tem : %d hum : %d\r\n", key_value, tem, hum);
		IoTGpioSetOutputVal(led_pin, led_value);
		//OS_MSleep(1000);
		//led_value = ~led_value;
		
		recv(cfd, recv_buf, sizeof(recv_buf), 0);

		memset(send_buf, 0, sizeof(send_buf));
		sprintf(send_buf, "{\"led\":\"%d\",\"key\":\"%d\",\"tem\":\"%d\",\"hum\":\"%d\"}",\
						led_value, key_value, tem, hum);		
		send(cfd,send_buf, strlen(send_buf),0);

		dev_dat = cJSON_Parse(recv_buf);
		//dev_dat = cJSON_CreateObject();
		//cJSON_AddStringToObject(dev_dat, "key", "key_value");
		//cJSON_AddStringToObject(dev_dat, "Title", "View from 15th Floor");
		//cJSON_AddItemToObject(dev_dat, "key", cJSON_CreateString("key_value"));
		led_value = cJSON_GetObjectItem(dev_dat, "led")->valuestring[0] - '0';		
		printf("led data : %d\r\n", led_value);
		cJSON_Delete(dev_dat);
	}
}

static void wifi_connect(char *ssid, char *passwd)
{
	char *ssid_want_connect = ssid;
	char *psk = passwd;

	if (WIFI_SUCCESS != EnableWifi()) {
		printf("Error: EnableWifi fail.\n");
		return;
	}
	printf("EnableWifi Success.\n");

	if (WIFI_STA_ACTIVE == IsWifiActive())
		printf("Wifi is active.\n");

	OS_Sleep(1);

	if (WIFI_SUCCESS != Scan()) {
		printf("Error: Scan fail.\n");
		return;
	}
	printf("Wifi Scan Success.\n");

	OS_Sleep(1);

	WifiScanInfo scan_results[30];
	unsigned int scan_num = 30;

	if (WIFI_SUCCESS != GetScanInfoList(scan_results, &scan_num)) {
		printf("Error: GetScanInfoList fail.\n");
		return;
	}

	WifiDeviceConfig config = { 0 };
	int netId = 0;

	int i;
	for (i = 0; i < scan_num; i++) {
		if (0 == strcmp(scan_results[i].ssid, ssid_want_connect)) {
			memcpy(config.ssid, scan_results[i].ssid,
			       WIFI_MAX_SSID_LEN);
			memcpy(config.bssid, scan_results[i].bssid,
			       WIFI_MAC_LEN);
			strcpy(config.preSharedKey, psk);
			config.securityType = scan_results[i].securityType;
			config.wapiPskType = WIFI_PSK_TYPE_ASCII;
			config.freq = scan_results[i].frequency;
			break;
		}
	}

	if (i >= scan_num) {
		printf("Error: No found ssid in scan_results\n");
		return;
	}
	printf("GetScanInfoList Success.\n");

	if (WIFI_SUCCESS != AddDeviceConfig(&config, &netId)) {
		printf("Error: AddDeviceConfig Fail\n");
		return;
	}
	printf("AddDeviceConfig Success.\n");

	if (WIFI_SUCCESS != ConnectTo(netId)) {
		printf("Error: ConnectTo Fail\n");
		return;
	}
	printf("ConnectTo Success\n");

	OS_Sleep(3);

	WifiLinkedInfo get_linked_res;

	if (WIFI_SUCCESS != GetLinkedInfo(&get_linked_res)) {
		printf("Error: GetLinkedInfo Fail\n");
		return;
	}
	printf("GetLinkedInfo Success.\n");

	printf("ssid: %s\n", get_linked_res.ssid);
	printf("bssid: ");
	for (int j = 0; j < WIFI_MAC_LEN; j++) {
		printf("%02X", get_linked_res.bssid[j]);
	}
	printf("\n");
	printf("rssi: %d\n", get_linked_res.rssi);

	unsigned char get_mac_res[WIFI_MAC_LEN];

	if (WIFI_SUCCESS != GetDeviceMacAddress(get_mac_res)) {
		printf("Error: GetDeviceMacAddress Fail\n");
		return;
	}
	printf("GetDeviceMacAddress Success.\n");
	for (int j = 0; j < WIFI_MAC_LEN - 1; j++) {
		printf("%02X:", get_mac_res[j]);
	}
	printf("%02X\n", get_mac_res[WIFI_MAC_LEN - 1]);
}


void SmartHome(void)
{
	if (OS_ThreadCreate(&g_main_thread, "MainThread", MainThread, NULL,
			    OS_THREAD_PRIO_APP, 8 * 1024) != OS_OK) {
		printf("[ERR] Create MainThread Failed\n");
	}
}

SYS_RUN(SmartHome);
